home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
utils
/
tweak16b
/
vgalib.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-22
|
7KB
|
387 lines
#include <dos.h>
#include <conio.h>
#include <string.h>
#include "misc.hpp"
#include "screen.hpp"
#include "vgalib.hpp"
GraphicsAPI::GraphicsAPI(int xr, int yr, int vxr, int vyr, int clrs)
{
int segm, offs;
xres = xr;
yres = yr;
vxres = vxr;
vyres = vyr;
colors = clrs;
libID = "Generic Graphics";
asm {
push bp
mov ax, 1130h
mov bh, 03h
int 10h
mov ax, bp
pop bp
mov [segm], es
mov [offs], ax
}
font = (unsigned char *)MK_FP(segm, offs);
fontHeight = fontWidth = 8;
}
void GraphicsAPI::hLine(int x, int y, int l)
{
while (l--)
putPixel(x++, y);
}
void GraphicsAPI::vLine(int x, int y, int l)
{
while (l--)
putPixel(x, y++);
}
/*
* Generic line drawing routine, using Bresenham's algorithm.
* Taken from Richard Wilton: "PC & PS/2 Video Systems" p. 166-7
*/
void GraphicsAPI::line(int x1, int y1, int x2, int y2)
{
if (x1==x2)
{
sort(y1, y2);
vLine(x1, y1, y2-y1+1);
return;
}
if (y1==y2)
{
sort(x1, x2);
hLine(x1, y1, x2-x1+1);
}
int dx = absolute(x2-x1);
int dy = absolute(y2-y1);
if (dx >= dy)
{
if (x1>x2)
{
swap(x1, x2);
swap(y1, y2);
}
int yincr = 1;
if (y2<y1)
yincr = -yincr;
int d = 2 * dy - dx;
int aincr = 2 * (dy - dx);
int bincr = 2 * dy;
int x = x1;
int y = y1;
putPixel(x, y);
while (++x <= x2)
{
if (d >= 0)
{
y += yincr;
d += aincr;
}
else
d += bincr;
putPixel(x, y);
}
}
else
{
if (y1>y2)
{
swap(x1, x2);
swap(y1, y2);
}
int xincr = 1;
if (x2<x1)
xincr = -xincr;
int d = 2*dx - dy;
int aincr = 2 * (dx - dy);
int bincr = 2 * dx;
int x = x1;
int y = y1;
putPixel(x, y);
while (++y <= y2)
{
if (d >= 0)
{
x += xincr;
d += aincr;
}
else
d += bincr;
putPixel(x, y);
}
}
}
void GraphicsAPI::rectangle(int x1, int y1, int x2, int y2)
{
sort(x1, x2);
sort(y1, y2);
hLine(x1, y1, x2-x1);
hLine(x1, y2, x2-x1);
vLine(x1, y1, y2-y1);
vLine(x2, y1, y2-y1);
}
void GraphicsAPI::bar(int x1, int y1, int x2, int y2)
{
int width = x2-x1+1;
for (int y = y1; y < y2; ++y)
hLine(x1, y, width);
}
void GraphicsAPI::wipe()
{
bar(0, 0, vxres, vyres);
}
void GraphicsAPI::putChar(int x, int y, int ch)
{
unsigned char *fptr = font + fontHeight*ch;
for (int j=0; j<fontHeight; ++j, ++fptr)
{
char mask = *fptr;
for (int i=0; i<fontWidth; ++i)
{
asm shl [mask], 1;
asm jnc skip
putPixel(x+i, y+j, color);
skip:
}
}
}
void GraphicsAPI::putText(int x, int y, char *txt)
{
switch (hJustify)
{
case HCENTER:
x -= fontWidth * strlen(txt) / 2;
break;
case RIGHT:
x -= fontWidth * strlen(txt);
break;
}
switch (vJustify)
{
case VCENTER:
y -= fontHeight / 2;
break;
case BOTTOM:
y -= fontHeight;
break;
}
while (*txt)
{
putChar(x, y, *(txt++));
x += fontWidth;
}
}
void GraphicsAPI::setTextJustify(HJustify h, VJustify v)
{
hJustify = h;
vJustify = v;
}
/*
* VGAGraphicsAPI
*/
unsigned char *VGAGraphicsAPI::videoBuf =
(unsigned char *)MK_FP(0xa000,0);
VGAGraphicsAPI::VGAGraphicsAPI(int xr, int yr, int vxr, int xb, int clrs)
: GraphicsAPI(xr, yr, vxr, 65536L/xb, clrs), xbytes(xb)
{
libID = "VGA Graphics";
outp(0x3ce, 0x05);
int t = inp(0x3cf);
outpw(0x3ce, 0x05 | (t & 0xfc) << 8); // write mode 0
outpw(0x3c4, 0x0f02); // enable all planes
}
void VGAGraphicsAPI::syncWithRefresh()
{
while (inp(0x3da)&0x8);
while (!(inp(0x3da)&0x8));
}
unsigned VGAGraphicsAPI::getOffset(int x, int y)
{
return y * xbytes + x/(vxres/xbytes);
}
void VGAGraphicsAPI::setBase(int x=0, int y=0)
{
unsigned offset = getOffset(x,y);
inp(0x3da);
outp(0x3c0, 0x33);
outp(0x3c0, getPelPan(x));
outpw(0x3d4, 0x0c | (offset & 0xff00));
outpw(0x3d4, 0x0d | (offset & 0x00ff)<<8);
syncWithRefresh();
}
/*
* Planar16
*/
Planar16::Planar16(int xr, int yr, int vxr)
: VGAGraphicsAPI(xr, yr, vxr, vxr>>3, 16)
{
libID = "4-plane 16-color mode";
outpw(0x3ce, 0x0f01); // enable set/reset
}
void Planar16::putPixel(int x, int y, int c)
{
outpw(0x3ce, 0x00 | (c<<8)); // set/reset to select color
outpw(0x3ce, 0x08 | 0x8000>>(x&7)); // bit mask to select bit
unsigned char *pos = graphScr+y*xbytes+(x>>3);
*pos = *pos;
}
int Planar16::getPixel(int x, int y)
{
return videoBuf[y*xbytes+x];
}
void Planar16::hLine(int x, int y, int l)
{
outpw(0x3ce, 0x00 | (color<<8)); // set/reset to select color
unsigned char *pos = graphScr+y*xbytes+(x>>3);
int mask;
int shift = x & 7;
if (shift > 0)
{
mask = 0x00ff >> shift;
l -= 8 - shift;
if (l<0)
mask &= 0xff << -l;
outpw(0x3ce, 0x08 | mask << 8); // bit mask to select first bits
*pos = *pos;
++pos;
}
if (l >= 8)
{
outpw(0x3ce, 0xff08); // bit mask to select 8 bits
memset(pos, 0, l>>3);
pos += l>>3;
l -= l & 0xf8;
}
if (l >= 0)
{
mask = 0xff00 << (8-l);
outpw(0x3ce, 0x08 | mask); // bit mask to select last bits
*pos = *pos;
}
}
int Planar16::getPelPan(int x)
{
return x & 7;
}
/*
* Chained256
*/
Chained256::Chained256(int xr, int yr, int vxr)
: VGAGraphicsAPI(xr, yr, vxr, vxr, 256)
{
libID = "Chained 256-color mode";
}
void Chained256::putPixel(int x, int y, int c)
{
videoBuf[y*xbytes+x] = c;
}
int Chained256::getPixel(int x, int y)
{
return videoBuf[y*xbytes+x];
}
void Chained256::hLine(int x, int y, int l)
{
memset(graphScr+y*xbytes+x, color, l);
}
unsigned Chained256::getOffset(int x, int y)
{
return (y * xbytes + x/(vxres/xbytes)) >> 2;
}
int Chained256::getPelPan(int x)
{
return 2*(x & 3);
}
/*
* Unchained256
*/
Unchained256::Unchained256(int xr, int yr, int vxr)
: VGAGraphicsAPI(xr, yr, vxr, vxr>>2, 256)
{
libID = "Unchained 256-color mode";
}
void Unchained256::putPixel(int x, int y, int c)
{
outpw(0x3c4, 0x02 | 0x0100<<(x&3));
videoBuf[y*xbytes+(x>>2)] = c;
}
int Unchained256::getPixel(int x, int y)
{
return videoBuf[y*xbytes+x];
}
void Unchained256::hLine(int x, int y, int l)
{
unsigned char *pos = graphScr+y*xbytes+(x>>2);
int mask;
int shift = x & 3;
if (shift > 0)
{
mask = 0x000f << shift & 0x000f;
l -= 4-shift;
if (l<0)
mask &= 0x0f >> -l;
outpw(0x3c4, 0x02 | mask << 8); // write enable first pixels
*(pos++) = color;
}
if (l >= 4)
{
outpw(0x3c4, 0x0f02); // write enable 4 pixels
memset(pos, color, l>>2);
pos += l>>2;
l -= l & 0xfc;
}
if (l >= 0)
{
mask = 0x0f00 >> (4-l) & 0x0f00;
outpw(0x3c4, 0x02 | mask); // write enable last pixels
*pos = color;
}
}
int Unchained256::getPelPan(int x)
{
return 2*(x & 3);
}